package com.ruoyi.paipan.common;

import java.util.*;

/**
 * @author tiemeng
 * * @date 2024/11/25
 */
public class Cdnongli {
    private int MIN_YEAR = 1891;
    private int MAX_YEAR = 2100;
    List<List<Integer>> lunarInfo = new ArrayList<List<Integer>>() {{
        add(Arrays.asList(0, 2, 9, 21936));
        add(Arrays.asList(6, 1, 30, 9656));
        add(Arrays.asList(0, 2, 17, 9584));
        add(Arrays.asList(0, 2, 6, 21168));
        add(Arrays.asList(5, 1, 26, 43344));
        add(Arrays.asList(0, 2, 13, 59728));
        add(Arrays.asList(0, 2, 2, 27296));
        add(Arrays.asList(3, 1, 22, 44368));
        add(Arrays.asList(0, 2, 10, 43856));
        add(Arrays.asList(8, 1, 31, 19304));
        add(Arrays.asList(0, 2, 19, 19168));
        add(Arrays.asList(0, 2, 8, 42352));
        add(Arrays.asList(5, 1, 29, 21096));
        add(Arrays.asList(0, 2, 16, 53856));
        add(Arrays.asList(0, 2, 4, 55632));
        add(Arrays.asList(4, 1, 25, 27304));
        add(Arrays.asList(0, 2, 13, 22176));
        add(Arrays.asList(0, 2, 2, 39632));
        add(Arrays.asList(2, 1, 22, 19176));
        add(Arrays.asList(0, 2, 10, 19168));
        add(Arrays.asList(6, 1, 30, 42200));
        add(Arrays.asList(0, 2, 18, 42192));
        add(Arrays.asList(0, 2, 6, 53840));
        add(Arrays.asList(5, 1, 26, 54568));
        add(Arrays.asList(0, 2, 14, 46400));
        add(Arrays.asList(0, 2, 3, 54944));
        add(Arrays.asList(2, 1, 23, 38608));
        add(Arrays.asList(0, 2, 11, 38320));
        add(Arrays.asList(7, 2, 1, 18872));
        add(Arrays.asList(0, 2, 20, 18800));
        add(Arrays.asList(0, 2, 8, 42160));
        add(Arrays.asList(5, 1, 28, 45656));
        add(Arrays.asList(0, 2, 16, 27216));
        add(Arrays.asList(0, 2, 5, 27968));
        add(Arrays.asList(4, 1, 24, 44456));
        add(Arrays.asList(0, 2, 13, 11104));
        add(Arrays.asList(0, 2, 2, 38256));
        add(Arrays.asList(2, 1, 23, 18808));
        add(Arrays.asList(0, 2, 10, 18800));
        add(Arrays.asList(6, 1, 30, 25776));
        add(Arrays.asList(0, 2, 17, 54432));
        add(Arrays.asList(0, 2, 6, 59984));
        add(Arrays.asList(5, 1, 26, 27976));
        add(Arrays.asList(0, 2, 14, 23248));
        add(Arrays.asList(0, 2, 4, 11104));
        add(Arrays.asList(3, 1, 24, 37744));
        add(Arrays.asList(0, 2, 11, 37600));
        add(Arrays.asList(7, 1, 31, 51560));
        add(Arrays.asList(0, 2, 19, 51536));
        add(Arrays.asList(0, 2, 8, 54432));
        add(Arrays.asList(6, 1, 27, 55888));
        add(Arrays.asList(0, 2, 15, 46416));
        add(Arrays.asList(0, 2, 5, 22176));
        add(Arrays.asList(4, 1, 25, 43736));
        add(Arrays.asList(0, 2, 13, 9680));
        add(Arrays.asList(0, 2, 2, 37584));
        add(Arrays.asList(2, 1, 22, 51544));
        add(Arrays.asList(0, 2, 10, 43344));
        add(Arrays.asList(7, 1, 29, 46248));
        add(Arrays.asList(0, 2, 17, 27808));
        add(Arrays.asList(0, 2, 6, 46416));
        add(Arrays.asList(5, 1, 27, 21928));
        add(Arrays.asList(0, 2, 14, 19872));
        add(Arrays.asList(0, 2, 3, 42416));
        add(Arrays.asList(3, 1, 24, 21176));
        add(Arrays.asList(0, 2, 12, 21168));
        add(Arrays.asList(8, 1, 31, 43344));
        add(Arrays.asList(0, 2, 18, 59728));
        add(Arrays.asList(0, 2, 8, 27296));
        add(Arrays.asList(6, 1, 28, 44368));
        add(Arrays.asList(0, 2, 15, 43856));
        add(Arrays.asList(0, 2, 5, 19296));
        add(Arrays.asList(4, 1, 25, 42352));
        add(Arrays.asList(0, 2, 13, 42352));
        add(Arrays.asList(0, 2, 2, 21088));
        add(Arrays.asList(3, 1, 21, 59696));
        add(Arrays.asList(0, 2, 9, 55632));
        add(Arrays.asList(7, 1, 30, 23208));
        add(Arrays.asList(0, 2, 17, 22176));
        add(Arrays.asList(0, 2, 6, 38608));
        add(Arrays.asList(5, 1, 27, 19176));
        add(Arrays.asList(0, 2, 15, 19152));
        add(Arrays.asList(0, 2, 3, 42192));
        add(Arrays.asList(4, 1, 23, 53864));
        add(Arrays.asList(0, 2, 11, 53840));
        add(Arrays.asList(8, 1, 31, 54568));
        add(Arrays.asList(0, 2, 18, 46400));
        add(Arrays.asList(0, 2, 7, 46752));
        add(Arrays.asList(6, 1, 28, 38608));
        add(Arrays.asList(0, 2, 16, 38320));
        add(Arrays.asList(0, 2, 5, 18864));
        add(Arrays.asList(4, 1, 25, 42168));
        add(Arrays.asList(0, 2, 13, 42160));
        add(Arrays.asList(10, 2, 2, 45656));
        add(Arrays.asList(0, 2, 20, 27216));
        add(Arrays.asList(0, 2, 9, 27968));
        add(Arrays.asList(6, 1, 29, 44448));
        add(Arrays.asList(0, 2, 17, 43872));
        add(Arrays.asList(0, 2, 6, 38256));
        add(Arrays.asList(5, 1, 27, 18808));
        add(Arrays.asList(0, 2, 15, 18800));
        add(Arrays.asList(0, 2, 4, 25776));
        add(Arrays.asList(3, 1, 23, 27216));
        add(Arrays.asList(0, 2, 10, 59984));
        add(Arrays.asList(8, 1, 31, 27432));
        add(Arrays.asList(0, 2, 19, 23232));
        add(Arrays.asList(0, 2, 7, 43872));
        add(Arrays.asList(5, 1, 28, 37736));
        add(Arrays.asList(0, 2, 16, 37600));
        add(Arrays.asList(0, 2, 5, 51552));
        add(Arrays.asList(4, 1, 24, 54440));
        add(Arrays.asList(0, 2, 12, 54432));
        add(Arrays.asList(0, 2, 1, 55888));
        add(Arrays.asList(2, 1, 22, 23208));
        add(Arrays.asList(0, 2, 9, 22176));
        add(Arrays.asList(7, 1, 29, 43736));
        add(Arrays.asList(0, 2, 18, 9680));
        add(Arrays.asList(0, 2, 7, 37584));
        add(Arrays.asList(5, 1, 26, 51544));
        add(Arrays.asList(0, 2, 14, 43344));
        add(Arrays.asList(0, 2, 3, 46240));
        add(Arrays.asList(4, 1, 23, 46416));
        add(Arrays.asList(0, 2, 10, 44368));
        add(Arrays.asList(9, 1, 31, 21928));
        add(Arrays.asList(0, 2, 19, 19360));
        add(Arrays.asList(0, 2, 8, 42416));
        add(Arrays.asList(6, 1, 28, 21176));
        add(Arrays.asList(0, 2, 16, 21168));
        add(Arrays.asList(0, 2, 5, 43312));
        add(Arrays.asList(4, 1, 25, 29864));
        add(Arrays.asList(0, 2, 12, 27296));
        add(Arrays.asList(0, 2, 1, 44368));
        add(Arrays.asList(2, 1, 22, 19880));
        add(Arrays.asList(0, 2, 10, 19296));
        add(Arrays.asList(6, 1, 29, 42352));
        add(Arrays.asList(0, 2, 17, 42208));
        add(Arrays.asList(0, 2, 6, 53856));
        add(Arrays.asList(5, 1, 26, 59696));
        add(Arrays.asList(0, 2, 13, 54576));
        add(Arrays.asList(0, 2, 3, 23200));
        add(Arrays.asList(3, 1, 23, 27472));
        add(Arrays.asList(0, 2, 11, 38608));
        add(Arrays.asList(11, 1, 31, 19176));
        add(Arrays.asList(0, 2, 19, 19152));
        add(Arrays.asList(0, 2, 8, 42192));
        add(Arrays.asList(6, 1, 28, 53848));
        add(Arrays.asList(0, 2, 15, 53840));
        add(Arrays.asList(0, 2, 4, 54560));
        add(Arrays.asList(5, 1, 24, 55968));
        add(Arrays.asList(0, 2, 12, 46496));
        add(Arrays.asList(0, 2, 1, 22224));
        add(Arrays.asList(2, 1, 22, 19160));
        add(Arrays.asList(0, 2, 10, 18864));
        add(Arrays.asList(7, 1, 30, 42168));
        add(Arrays.asList(0, 2, 17, 42160));
        add(Arrays.asList(0, 2, 6, 43600));
        add(Arrays.asList(5, 1, 26, 46376));
        add(Arrays.asList(0, 2, 14, 27936));
        add(Arrays.asList(0, 2, 2, 44448));
        add(Arrays.asList(3, 1, 23, 21936));
        add(Arrays.asList(0, 2, 11, 37744));
        add(Arrays.asList(8, 2, 1, 18808));
        add(Arrays.asList(0, 2, 19, 18800));
        add(Arrays.asList(0, 2, 8, 25776));
        add(Arrays.asList(6, 1, 28, 27216));
        add(Arrays.asList(0, 2, 15, 59984));
        add(Arrays.asList(0, 2, 4, 27424));
        add(Arrays.asList(4, 1, 24, 43872));
        add(Arrays.asList(0, 2, 12, 43744));
        add(Arrays.asList(0, 2, 2, 37600));
        add(Arrays.asList(3, 1, 21, 51568));
        add(Arrays.asList(0, 2, 9, 51552));
        add(Arrays.asList(7, 1, 29, 54440));
        add(Arrays.asList(0, 2, 17, 54432));
        add(Arrays.asList(0, 2, 5, 55888));
        add(Arrays.asList(5, 1, 26, 23208));
        add(Arrays.asList(0, 2, 14, 22176));
        add(Arrays.asList(0, 2, 3, 42704));
        add(Arrays.asList(4, 1, 23, 21224));
        add(Arrays.asList(0, 2, 11, 21200));
        add(Arrays.asList(8, 1, 31, 43352));
        add(Arrays.asList(0, 2, 19, 43344));
        add(Arrays.asList(0, 2, 7, 46240));
        add(Arrays.asList(6, 1, 27, 46416));
        add(Arrays.asList(0, 2, 15, 44368));
        add(Arrays.asList(0, 2, 5, 21920));
        add(Arrays.asList(4, 1, 24, 42448));
        add(Arrays.asList(0, 2, 12, 42416));
        add(Arrays.asList(0, 2, 2, 21168));
        add(Arrays.asList(3, 1, 22, 43320));
        add(Arrays.asList(0, 2, 9, 26928));
        add(Arrays.asList(7, 1, 29, 29336));
        add(Arrays.asList(0, 2, 17, 27296));
        add(Arrays.asList(0, 2, 6, 44368));
        add(Arrays.asList(5, 1, 26, 19880));
        add(Arrays.asList(0, 2, 14, 19296));
        add(Arrays.asList(0, 2, 3, 42352));
        add(Arrays.asList(4, 1, 24, 21104));
        add(Arrays.asList(0, 2, 10, 53856));
        add(Arrays.asList(8, 1, 30, 59696));
        add(Arrays.asList(0, 2, 18, 54560));
        add(Arrays.asList(0, 2, 7, 55968));
        add(Arrays.asList(6, 1, 27, 27472));
        add(Arrays.asList(0, 2, 15, 22224));
        add(Arrays.asList(0, 2, 5, 19168));
        add(Arrays.asList(4, 1, 25, 42216));
        add(Arrays.asList(0, 2, 12, 42192));
        add(Arrays.asList(0, 2, 1, 53584));
        add(Arrays.asList(2, 1, 21, 55592));
        add(Arrays.asList(0, 2, 9, 54560));
    }};
    List<String> SolarToLunar(int year, int month, int date)
    {
        List<Integer> yearData = this.lunarInfo.get(year - this.MIN_YEAR);
        if (year == this.MIN_YEAR && month <= 2 && date <= 9) {
            return Arrays.asList("1891", "正月", "初一", "辛卯", "1", "1", "兔");
        }
        return this.getLunarByBetween(year, this.getDaysBetweenSolar(year, month, date, yearData.get(1), yearData.get(2)));
    }

    int getDaysBetweenSolar(int year, int cmonth, int cdate, int dmonth, int ddate)
    {
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.YEAR,year);
        instance.set(Calendar.MONTH,cmonth-1);
        instance.set(Calendar.DAY_OF_MONTH,cdate);
        instance.set(Calendar.HOUR_OF_DAY,0);
        instance.set(Calendar.MINUTE,0);
        long a = instance.getTimeInMillis();
        instance.set(Calendar.YEAR,year);
        instance.set(Calendar.MONTH,dmonth-1);
        instance.set(Calendar.DAY_OF_MONTH,ddate);
        instance.set(Calendar.HOUR_OF_DAY,0);
        instance.set(Calendar.MINUTE,0);
        long b = instance.getTimeInMillis();
        return (int)Math.round((a-b)/24.0/3600/1000);
    }

    Integer getLunarYearDays(int year)
    {
        ArrayList<Integer> monthArray = this.getLunarYearMonths(year);
        int len = monthArray.size();
        return (monthArray.get(len - 1) == 0 ? monthArray.get(len - 2) : monthArray.get(len - 1));
    }

    ArrayList<Integer> getLunarYearMonths(int year)
    {
        List<String> monthData = this.getLunarMonths(year);
        ArrayList<Integer> res = new ArrayList<>();
        int temp;
        List<Integer> yearData = this.lunarInfo.get(year - this.MIN_YEAR);
        int len = (yearData.get(0) == 0 ? 12 : 13);
        for (int i = 0; i < len; i++) {
            temp = 0;
            for (int j = 0; j <= i; j++) {
                temp += Integer.parseInt(monthData.get(j));
            }
            res.add(temp);
        }
        return res;
    }

    List<String> getLunarMonths(int year)
    {
        List<Integer> yearData = this.lunarInfo.get(year - this.MIN_YEAR);
        int leapMonth = yearData.get(0);
        String bit = Integer.toBinaryString(yearData.get(3));
        List<String> bitArray = new ArrayList<>();
        for (int i = 0; i < bit.length(); i++) {
            bitArray.add(bit.substring(i,i+1));
        }
        for (int k = 0, klen = 16 - bitArray.size(); k < klen; k++) {
            bitArray.add(0,"0");
        }
        bitArray = (List<String>) bitArray.subList(0, (leapMonth == 0 ? 12 : 13));
        for (int i = 0; i < bitArray.size(); i++) {
            int s = Integer.parseInt(bitArray.get(i));
            bitArray.set(i, String.valueOf(s+29));
        }
        return  bitArray;
    }
    Integer getLeapMonth(int year)
    {
        List<Integer> yearData = this.lunarInfo.get(year - this.MIN_YEAR);
        return yearData.get(0);
    }

    ArrayList<String> getLunarByBetween(int year, int between)
    {
        ArrayList<String> lunarArray = new ArrayList<>();
        ArrayList<Integer> yearMonth;
        int t = 0;
        int e = 0;
        int leapMonth = 0;
        String m = "";
        if (between == 0) {
            lunarArray.add(String.valueOf(year));
            lunarArray.add("正月");
            lunarArray.add("初一");
            t = 1;
            e = 1;
        } else {
            if(between < 0){
                year = year-1;
            }
            yearMonth = this.getLunarYearMonths(year);
            leapMonth = this.getLeapMonth(year);
            between = between > 0 ? between : (this.getLunarYearDays(year) + between);
            for (int i = 0; i < 13; i++) {
                if (between == yearMonth.get(i)) {
                    t = i + 2;
                    e = 1;
                    break;
                } else if (between < yearMonth.get(i)) {
                    t = i + 1;
                    e = between - (i== 0 || (yearMonth.get(i - 1) == null) ? 0 : yearMonth.get(i - 1)) + 1;
                    break;
                }
            }
            m = (leapMonth != 0 && t == leapMonth + 1) ? ("闰" + this.getCapitalNum(t - 1, true)) : this.getCapitalNum((leapMonth != 0 && leapMonth + 1 < t ? (t - 1) : t), true);
            lunarArray.add(String.valueOf(year));
            lunarArray.add(String.valueOf(m));
            lunarArray.add(this.getCapitalNum(e, false));
        }
        lunarArray.add(this.getLunarYearName(year));
        lunarArray.add(String.valueOf(t));
        lunarArray.add(String.valueOf(e));
        lunarArray.add(this.getYearZodiac(year));
        lunarArray.add(String.valueOf(leapMonth));
        return lunarArray;
    }
    String getLunarYearName(int year)
    {
        List<String> sky = Arrays.asList("庚", "辛", "壬", "癸", "甲", "乙", "丙", "丁", "戊", "己");
        List<String> earth = Arrays.asList("申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未");
        String yearStr = year + "";
        return sky.get(Integer.parseInt(yearStr.substring(3,4))) + earth.get(year % 12);
    }

    String getYearZodiac(int year)
    {
        List<String> zodiac = Arrays.asList("猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊");
        return zodiac.get(year % 12);
    }
    String getCapitalNum(int num,boolean isMonth)
    {
        LinkedHashMap<String,String> dateHash = new LinkedHashMap<String,String>(){{
            put("0" , "");
            put("1" , "一");
            put("2" , "二");
            put("3" , "三");
            put("4" , "四");
            put("5" , "五");
            put("6" , "六");
            put("7" , "七");
            put("8" , "八");
            put("9" , "九");
            put("10", "十 ");
        }};
        LinkedHashMap<String,String> monthHash = new LinkedHashMap<String,String>(){{
            put("0" , "");
            put("1" , "正月");
            put("2" , "二月");
            put("3" , "三月");
            put("4" , "四月");
            put("5" , "五月");
            put("6" , "六月");
            put("7" , "七月");
            put("8" , "八月");
            put("9" , "九月");
            put("10", "十月");
            put("11", "冬月");
            put("12", "腊月");
        }};
        String res = "";
        if (isMonth) {
            res = monthHash.get(String.valueOf(num));
        } else {
            if (num <= 10) {
                res = "初" + dateHash.get(String.valueOf(num));
            } else if (num < 20) {
                res = "十" + dateHash.get(String.valueOf(num - 10));
            } else if (num == 20) {
                res = "二十";
            } else if (num < 30) {
                res = "廿" + dateHash.get(String.valueOf(num - 20));
            } else if (num == 30) {
                res = "三十";
            }
        }
        return res;
    }



}
